package com.eternal.data;

import android.app.Activity;
import android.app.Application;

import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.paging.PagedList;
import androidx.annotation.NonNull;

import com.alibaba.android.arouter.facade.Postcard;
import com.alibaba.android.arouter.launcher.ARouter;
import com.eternal.base.concat.BluetoothEvent;
import com.eternal.base.concat.DeviceModel;
import com.eternal.base.concat.TmpHum;
import com.eternal.base.data.HistoryRepository;
import com.eternal.base.data.RepositoryInjection;
import com.eternal.base.global.ActivityEvent;
import com.eternal.base.global.ProgressEvent;
import com.eternal.base.router.RouterActivityPath;
import com.eternal.framework.binding.command.BindingAction;
import com.eternal.framework.binding.command.BindingCommand;
import com.eternal.framework.bus.RxBus;
import com.eternal.framework.component.AppManager;
import com.eternal.framework.component.BaseViewModel;
import com.eternal.framework.utils.KLog;
import com.eternal.framework.utils.RxUtils;

import org.jetbrains.annotations.NotNull;

import io.reactivex.CompletableSource;
import io.reactivex.Maybe;
import io.reactivex.MaybeSource;
import io.reactivex.Observer;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

public class DataModel extends BaseViewModel {
    public DataModel(@NonNull Application application) {
        super(application);
    }

    public LiveData<PagedList<TmpHum>> history;
    public HistoryRepository repository;
    private String mac;
    private byte port;
    private Disposable timeDispose, dcDispose;
    private boolean ready;

    public void init(HistoryRepository repository, String mac, byte port) {
        this.mac = mac;
        this.port = port;
        this.repository = repository;
        ready = false;
    }

    public Single<Boolean> initHistory(final Consumer<Boolean> consumer, final Consumer<ActivityEvent> consumer2) {
        if (repository.isConnect(mac)) {
            return repository.refreshHistory(mac)
                    .subscribeOn(Schedulers.io())
                    .doOnSubscribe(new Consumer<Disposable>() {
                        @Override
                        public void accept(Disposable disposable) throws Exception {
                            register(disposable, consumer,consumer2);
                        }
                    })
                    .doOnComplete(new Action() {
                        @Override
                        public void run() throws Exception {
                            dcDispose.dispose();
                            dcDispose = null;
                            history = repository.getHistory(mac);
                            KLog.e("change history");
                            ready = true;
                            timeDispose = RxBus.getDefault().toObservable(Long.class)
                                    .flatMapCompletable(new Function<Long, CompletableSource>() {
                                        @Override
                                        public CompletableSource apply(Long aLong) throws Exception {
                                            return repository.refreshHistory(mac).subscribeOn(Schedulers.io());
                                        }
                                    }).subscribeOn(Schedulers.io())
                                    .compose(RxUtils.<Long>bindToLifecycle(getLifecycleProvider()))
                                    .subscribe();
                        }
                    }).andThen(isDegree());
        } else {
            history = repository.getHistory(mac);
            return isDegree();
        }
    }

    public Single<Boolean> isDegree() {
        return RepositoryInjection.providerDeviceRepository().isDegree(mac);
    }

    public boolean isReady() {
        return ready;
    }

    private void register(final Disposable disposable, final Consumer<Boolean> consumer, final Consumer<ActivityEvent> consumer2) {
        dcDispose = RxBus.getDefault().toObservable(BluetoothEvent.class)
                .flatMapMaybe(new Function<BluetoothEvent, MaybeSource<Boolean>>() {
                    @Override
                    public MaybeSource<Boolean> apply(BluetoothEvent event) throws Exception {
                        if (event.what == BluetoothEvent.DISCONNECT && mac.equals(event.obj)) {
                            disposable.dispose();
                            history = repository.getHistory(mac);
                            return isDegree().subscribeOn(Schedulers.io()).toMaybe();
                        }
                        return Maybe.empty();
                    }
                }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                .subscribe(consumer);
        addSubscribe(dcDispose);
        addSubscribe(RxBus.getDefault()
                .toObservable(ActivityEvent.class)
                .subscribe(consumer2));
    }

    public boolean isConnect() {
        return repository.isConnect(mac);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume() {
        if (ready) {
            timeDispose = RxBus.getDefault().toObservable(Long.class)
                    .compose(RxUtils.<Long>bindToLifecycle(getLifecycleProvider()))
                    .flatMapCompletable(new Function<Long, CompletableSource>() {
                        @Override
                        public CompletableSource apply(Long aLong) throws Exception {
                            return repository.refreshHistory(mac).subscribeOn(Schedulers.io());
                        }
                    }).subscribeOn(Schedulers.io()).subscribe();
            repository.refreshHistory(mac)
                    .compose(RxUtils.<Boolean>bindToLifecycle(getLifecycleProvider()))
                    .subscribeOn(Schedulers.io())
                    .subscribe();

        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void onPause() {
        if (timeDispose != null) {
            timeDispose.dispose();
        }
    }

    public BindingCommand<Void> onExport = new BindingCommand<Void>(new BindingAction() {
        @Override
        public void call() {
            Activity activity = AppManager.getAppManager().currentActivity();
            Postcard postcard = ARouter.getInstance().build(RouterActivityPath.Export.PAGE_EXPORT)
                    .withString(ActivityEvent.DEVICE_MAC, mac);
            if (repository.isConnect(mac)) {
                postcard.withString(ActivityEvent.DEVICE_TIME, null);
            } else {
                postcard.withString(ActivityEvent.DEVICE_TIME, activity.getIntent().getStringExtra(ActivityEvent.DEVICE_TIME));
            }
            postcard.withTransition(R.anim.right_in, R.anim.left_out).navigation(activity);
        }
    });

//    public void register() {
//        addSubscribe(RxBus.getDefault()
//                .toObservable(ActivityEvent.class)
//                .subscribe(new Consumer<ActivityEvent>() {
//                    @Override
//                    public void accept(ActivityEvent event) throws Exception {
//                        if (event.what == ActivityEvent.SET_DEVICE_MODEL_INFO_DEGREE) {
//                            DeviceModel info = (DeviceModel) event.obj;
//                            if (info != null) {
//                                ready = true;
//                                onResume();
//                            }
//                        }
//                    }
//                }));
//    }
}
